﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ThiefRun.Util.Graph
{
    public class Graph<N>
    {
        #region Constants
        // Constants
        #endregion Constants

        #region Properties
        // Properties
        protected List<Node<N>> nodes;
        protected List<Edge<Node<N>>> edges;
        #endregion Properties

        #region Computed Properties
        // Computed Propertiess
        public List<Node<N>> Nodes { get { return nodes; } }
        public List<Edge<Node<N>>> Edges { get { return edges; } }
        #endregion

        #region Methods
        // Methods

        /// <summary>
        /// Initialize the Graph object.
        /// </summary>
        /// <param name="name">The level that will be loaded.</param>
        /// <param name="size">Provides the components of the size of the tile.</param>
        public Graph()
        {
            this.nodes = new List<Node<N>>();
            this.edges = new List<Edge<Node<N>>>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        public void AddNode(N data)
        {
            Node<N> node = new Node<N>(data);
            nodes.Add(node);
        }

        /// <summary>
        /// Add an edge between two nodes.
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        public void AddEdge(Node<N> left, Node<N> right)
        {
            Edge<Node<N>> edge = new Edge<Node<N>>(left, right);
            edges.Add(edge);
        }

        /// <summary>
        /// Find the nodes adjacent to the parameter.
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public List<Node<N>> AdjacentNodes(Node<N> node)
        {
            List<Node<N>> adj = new List<Node<N>>();

            foreach (Edge<Node<N>> edge in edges)
            {
                // The node was found.
                if (edge.Left == node)
                {
                    adj.Add(edge.Right);
                }
            }

            return adj;
        }

        /// <summary>
        /// Find the edges adjacent to the parameter.
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public List<Edge<Node<N>>> AdjacentEdges(Node<N> node)
        {
            List<Edge<Node<N>>> adj = new List<Edge<Node<N>>>();

            foreach (Edge<Node<N>> edge in edges)
            {
                // The node was found.
                if (edge.Left == node)
                {
                    adj.Add(edge);
                }
            }

            return adj;
        }

        #endregion Methods
    }
}
